﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Streambolics
{
    public enum GlobalLogSeverity
    {
        Unknown,
        Debug,
        Trace,
        Information,
        Audit,
        Warning,
        Error,
        Fatal
    };


    public class GlobalLogEventArgs : EventArgs
    {
        private GlobalLogSeverity _Severity;
        private string _Message;
        private DateTime _TimeStamp;
        private Exception _Exception;

        public GlobalLogEventArgs (GlobalLogSeverity aSeverity, string aMessage, DateTime aTimeStamp, Exception aException)
        {
            _Severity = aSeverity;
            _Message = aMessage;
            _TimeStamp = aTimeStamp;
            _Exception = aException;
        }

        public GlobalLogSeverity Severity
        {
            get
            {
                if (_Severity == GlobalLogSeverity.Unknown)
                {
                    if (_Exception == null)
                    {
                        _Severity = GlobalLogSeverity.Information;
                    }
                    else
                    {
                        _Severity = GlobalLogSeverity.Error;
                    }
                }
                return _Severity;
            }
        }

        public string Message
        {
            get
            {
                if (_Message != null)
                {
                    return _Message;
                }
                if (_Exception != null)
                {
                    return _Exception.Message;
                }
                return _TimeStamp.ToString ();
            }
        }

        public DateTime TimeStamp
        {
            get
            {
                return _TimeStamp;
            }
        }

        public Exception Exception
        {
            get
            {
                return _Exception;
            }
        }

        public override string ToString ()
        {
            return _TimeStamp.ToUniversalString () + " " + Message;
        }

        public void AppendTo (StringBuilder sb)
        {
            sb.AppendLine (ToString ());
        }
    }

    public delegate void GlobalLogEventHandler (object sender, GlobalLogEventArgs e);

    public class GlobalLog
    {
        public static event GlobalLogEventHandler EventLogged;

        private static void DoLog (GlobalLogSeverity aSeverity, string aMessage, DateTime aTimeStamp, Exception aException)
        {
            if (EventLogged != null)
            {
                EventLogged (null, new GlobalLogEventArgs (aSeverity, aMessage, aTimeStamp, aException));
            }
        }

        public static void Log (string s)
        {
            DoLog (GlobalLogSeverity.Unknown, s, DateTime.Now, null);
        }

        public static void Log (string s, object o1)
        {
            Log (String.Format (s, o1.ToQuotedString()));
        }

        public static void Log (string s, object o1, object o2)
        {
            Log (String.Format (s, o1.ToQuotedString (), o2.ToQuotedString ()));
        }

        public static void Log (string s, object o1, object o2, object o3)
        {
            Log (String.Format (s, o1.ToQuotedString (), o2.ToQuotedString (), o3.ToQuotedString ()));
        }

        public static void Log (Exception ex)
        {
            Log (ex, ex.Message);
        }

        public static void Log (Exception ex, string s)
        {
            DoLog (GlobalLogSeverity.Error, s, DateTime.Now, ex);
        }

        public static void Log (Exception ex, string s, object o1)
        {
            Log (ex, String.Format (s, o1.ToQuotedString ()));
        }

        public static void Log (Exception ex, string s, object o1, object o2)
        {
            Log (ex, String.Format (s, o1.ToQuotedString (), o2.ToQuotedString ()));
        }

        public static void Log (Exception ex, string s, object o1, object o2, object o3)
        {
            Log (ex, String.Format (s, o1.ToQuotedString (), o2.ToQuotedString (), o3.ToQuotedString ()));
        }

    }
}
